home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / apps / database / ingres04.lzh / source / gutil / cvt.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-11-19  |  2.0 KB  |  132 lines

  1. #include <stdlib.h>
  2. #include <string.h>
  3.  
  4.  
  5. /*
  6.  *    ecvt converts to decimal
  7.  *    the number of digits is specified by ndigit
  8.  *    decpt is set to the position of the decimal point
  9.  *    sign is set to 0 for positive, 1 for negative
  10.  */
  11.  
  12. #ifdef IEEE
  13.  
  14. static int
  15. __isspecial(double f, char *bp)
  16. {
  17.     register struct bitdouble *ip = (struct bitdouble *) &f;
  18.  
  19.     if (!(ip->exp & 0x7ff))
  20.         return(0);
  21.     if (ip->mant1 || ip->mant2)
  22.         strcpy(bp, "NaN");
  23.     else if (ip->sign)
  24.         strcpy(bp, "-Infinity");
  25.     else
  26.         strcpy(bp, "Infinity");
  27.     return(1);
  28. }
  29.  
  30. #define    NDIG    512
  31. #else
  32. #define    NDIG    80
  33. #endif
  34.  
  35. static char*
  36. cvt(double arg, size_t ndigits, int *decpt, int *sign, int eflag)
  37. {
  38.     register int r2;
  39.     double fi, fj;
  40.     register char *p, *p1;
  41.     static char buf[NDIG];
  42.  
  43. #ifdef IEEE
  44.     /* XXX */
  45.     if (__isspecial(arg, buf))
  46.         return(buf);
  47. #endif
  48.     if (ndigits>=NDIG-1)
  49.         ndigits = NDIG-2;
  50.     r2 = 0;
  51.     *sign = 0;
  52.     p = &buf[0];
  53.     if (arg<0) {
  54.         *sign = 1;
  55.         arg = -arg;
  56.     }
  57.     (void)modf(arg, &fi);
  58.     arg -= fi;
  59.     p1 = &buf[NDIG];
  60.     /*
  61.      * Do integer part
  62.      */
  63.     if (fi != 0) {
  64.         p1 = &buf[NDIG];
  65.         while (fi != 0) {
  66.             double t;
  67.  
  68.             t = fi/10;
  69.             fj = modf(t, &fi);
  70.             fj = t - fi;
  71.             *--p1 = (int)((fj+.03)*10) + '0';
  72.             r2++;
  73.         }
  74.         while (p1 < &buf[NDIG])
  75.             *p++ = *p1++;
  76.     } else if (arg > 0) {
  77.         while ((fj = arg*10) < 1) {
  78.             arg = fj;
  79.             r2--;
  80.         }
  81.     }
  82.     p1 = &buf[ndigits];
  83.     if (eflag==0)
  84.         p1 += r2;
  85.     *decpt = r2;
  86.     if (p1 < &buf[0]) {
  87.         buf[0] = '\0';
  88.         return(buf);
  89.     }
  90.     while (p<=p1 && p<&buf[NDIG]) {
  91.         arg *= 10;
  92.         (void)modf(arg, &fj);
  93.         arg -= fj;
  94.         *p++ = (int)fj + '0';
  95.     }
  96.     if (p1 >= &buf[NDIG]) {
  97.         buf[NDIG-1] = '\0';
  98.         return(buf);
  99.     }
  100.     p = p1;
  101.     *p1 += 5;
  102.     while (*p1 > '9') {
  103.         *p1 = '0';
  104.         if (p1>buf)
  105.             ++*--p1;
  106.         else {
  107.             *p1 = '1';
  108.             (*decpt)++;
  109.             if (eflag==0) {
  110.                 if (p>buf)
  111.                     *p = '0';
  112.                 p++;
  113.             }
  114.         }
  115.     }
  116.     *p = '\0';
  117.     return(buf);
  118. }
  119.  
  120. char*
  121. ecvt(double arg, size_t ndigits, int *decpt, int *sign)
  122. {
  123.     return(cvt(arg, ndigits, decpt, sign, 1));
  124. }
  125.  
  126. char*
  127. fcvt(double arg, size_t ndigits, int *decpt, int *sign)
  128. {
  129.     return(cvt(arg, ndigits, decpt, sign, 0));
  130. }
  131.  
  132.